package com.dylan.历史.基础;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

/**
 * Created by Dylan on 2018/9/4.
 */
public class 泛型_协变与逆变 {

    public static void main(String[] args) {
        // 类型支持协变
        Number num = new Integer(0);

        // 数组支持协变
        Number[] numArr = new Integer[10];

        // 泛型不支持协变
//        ArrayList<Number> numList = new ArrayList<Integer>();

        // 使用通配符模拟协变
        ArrayList<? extends Number> numList = new ArrayList<Integer>();

        // 调用泛型函数式接口时，参数可以逆变为父类，用父类的引用调用相应的方法，返回可以协变为子类，父类引用是可以引用子类对象的
        Function<Person, Boy> fun1 = t -> {
            System.out.println(t.getName());
            return new Boy();
        };
        handle(fun1);
    }

    // Function的传入参数是逆变的，返回值是协变的
    private static void handle(Function<? super Man, ? extends Man> fun) {
        Man man = new Man();
        Man man1 = fun.apply(man);
        System.out.println(man1);
    }

    static class Person {
        public String getName() {
            return "我是人";
        }
    }

    static class Man extends Person {
        public String getStrength() {
            return "我很有力气";
        }
    }

    static class Boy extends Man {
        public String getClazz() {
            return "三年二班";
        }
    }

}
